package ca.scotthyndman.as2haxe.dom;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import ca.scotthyndman.as2haxe.dom.visitor.IVisitor;

/**
 * Represents an array literal.
 * 
 * ASArrayLiteral: [ASExpression {, ASExpression}*]
 */
public class ASArrayLiteral extends ASExpression {

	/**
	 * The "expressions" structural property of this node type.
	 */
	public static final ASChildListPropertyDescriptor ELEMENTS_PROPERTY = new ASChildListPropertyDescriptor(
			ASArrayLiteral.class, "elements", ASExpression.class);

	/**
	 * A list of property descriptors (element type:
	 * {@link ASPropertyDescriptor}), or null if uninitialized.
	 */
	private static final List<ASPropertyDescriptor> PROPERTY_DESCRIPTORS;

	static {
		List<Object> properyList = new ArrayList<Object>(2);
		createPropertyList(ASArrayLiteral.class, properyList);
		addProperty(ELEMENTS_PROPERTY, properyList);
		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
	}

	/**
	 * Returns a list of structural property descriptors for this node type.
	 * Clients must not modify the result.
	 * 
	 * @return a list of property descriptors (element type:
	 *         {@link ASPropertyDescriptor})
	 */
	public static List<ASPropertyDescriptor> propertyDescriptors() {
		return PROPERTY_DESCRIPTORS;
	}
	
	/**
	 * The elements in the array.
	 */
	private List<ASTNode> elements = new ASTNode.NodeList(ELEMENTS_PROPERTY);

	/**
	 * Constructs a new instance of ASArrayLiteral
	 * 
	 * @param ast
	 *            The abstract syntax tree that owns this element
	 */
	public ASArrayLiteral(AST ast) {
		super(ast);
	}

	//
	// ======== GETTERS / SETTERS
	//

	/**
	 * @return the elements
	 */
	public List<ASTNode> getElements() {
		return elements;
	}

	//
	// ======== INTERNAL PROPERTIES
	//

	/*
	 * (omit javadoc for this method) Method declared on ASTNode.
	 */
	final List<ASTNode> internalGetChildListProperty(
			ASChildListPropertyDescriptor property) {
		if (property == ELEMENTS_PROPERTY) {
			return getElements();
		}
		// allow default implementation to flag the error
		return super.internalGetChildListProperty(property);
	}

	//
	// ======== OVERRIDES
	//

	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer("[\n");
		Iterator<ASTNode> itr = getElements().iterator();
		while (itr.hasNext()) {
			buf.append(itr.next().toString());
			if (itr.hasNext())
				buf.append(", ");
			buf.append("\n");
		}

		return buf.append("]\n").toString();
	}

	@Override
	public void accept(IVisitor as2Visitor, boolean recursive) {
		recursive = as2Visitor.visit(this);

		if (recursive) {
			for (ASTNode expr : getElements()) {
				((ASExpression) expr).accept(as2Visitor, recursive);
			}
		}
	}
}
